package com.seadragon.apps.doctorcard.service.impl;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import com.seadragon.apps.doctorcard.model.Contact;
import com.seadragon.apps.doctorcard.repository.ChatRepository;
import com.seadragon.apps.doctorcard.repository.ContactRepository;
import com.seadragon.apps.doctorcard.service.CacheService;

@Service("cacheService")
public class CacheServiceImpl implements CacheService {
	public static final String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_~";

	@Autowired
	private ContactRepository contactRepository;

	@Autowired
	private ChatRepository chatRepository;

	private Map<String, Boolean> uuidMap;

	private Map<String, Boolean> emailMap;

	private Map<String, Boolean> doctorCardIdMap;

	private Map<String, Boolean> mobileMap;

	private Object lock;

	public CacheServiceImpl() {
		lock = new Object();
	}

	@Override
	public String getUUID() {
		init();
		String uuid = RandomStringUtils.random(24, chars);
		while (uuidMap.get(uuid) != null) {
			uuid = RandomStringUtils.random(24, chars);
		}
		uuidMap.put(uuid, true);
		return uuid;
	}

	@Override
	public void updateCache(Contact contact){
		init();
		if(contact.getEmail() != null){
			emailMap.put(contact.getEmail(), true);
		}
		if(contact.getDoctorCardId() != null){
			doctorCardIdMap.put(contact.getDoctorCardId(), true);
		}
		if(contact.getMobile() != null){
			mobileMap.put(contact.getMobile(), true);
		}
	}
	
	@Override
	public boolean isEmailExisted(String email){
		init();
		if(emailMap.get(email) == null){
			return false;
		}
		return true;
	}
	
	@Override
	public boolean isMobileExisted(String mobile){
		init();
		if(mobileMap.get(mobile) == null){
			return false;
		}
		return true;
	}
	
	@Override
	public boolean isDoctorCardIdExisted(String doctorCardId){
		init();
		if(doctorCardIdMap.get(doctorCardId) == null){
			return false;
		}
		return true;
	}
	
	private void init(){
		if (uuidMap == null || emailMap == null || doctorCardIdMap == null || mobileMap == null ) {
			synchronized (lock) {
				if (uuidMap == null || emailMap == null || doctorCardIdMap == null || mobileMap == null ) {
					emailMap = new ConcurrentHashMap<String, Boolean>();
					doctorCardIdMap = new ConcurrentHashMap<String, Boolean>();
					mobileMap = new ConcurrentHashMap<String, Boolean>();
					uuidMap = new ConcurrentHashMap<String, Boolean>();
					int offset = 0;
					int pageSize = 100;
					Page<Contact> page = this.contactRepository.findAll(new PageRequest(offset, pageSize));
					do{
						for(Contact contact : page.getContent()){
							if(contact.getEmail() != null){
								emailMap.put(contact.getEmail(), true);
							}
							if(contact.getDoctorCardId() != null){
								doctorCardIdMap.put(contact.getDoctorCardId(), true);
							}
							if(contact.getMobile() != null){
								mobileMap.put(contact.getMobile(), true);
							}
							uuidMap.put(contact.getUuid(), true);
						}
					}while(page.hasNext());
					
					List<String> uuids = this.chatRepository.findAllUuid();
					if (uuids != null) {
						for (String uuid : uuids) {
							uuidMap.put(uuid, true);
						}
					}
				}
			}
		}
	}
}
